package controllers

import (
	"encoding/json"
	"fmt"
	"log"
	"strconv"
	"strings"
	"time"

	"github.com/gocolly/colly"
)

type City struct {
	link    string
	stageCh chan string
	doorCh  chan string
	lineMap map[string]*LineData
	metro   Metro
}

func NewCity(link string, metro Metro) *City {
	return &City{link, make(chan string, 10), make(chan string, 10), make(map[string]*LineData), metro}
}

func (city *City) Listen() {
	city.Line()
	obj, _ := json.Marshal(city.metro)
	CreateFile(fmt.Sprintf("./data/%s.json", city.metro.CityKey), obj)
}

func (city *City) Line() {
	c := colly.NewCollector()
	index := 0

	c.OnHTML("div .ib-box ul li", func(e *colly.HTMLElement) {
		// log.Printf("Contains %s", e.Name)
		exit := false
		e.ForEach("font", func(_ int, el *colly.HTMLElement) {
			// log.Printf("ForEach %s", el.Text)
			// log.Printf("Contains %s", el.Text)
			if strings.Contains(el.Text, "未开通") {
				exit = true
				return
			}
		})
		if exit {
			// log.Printf("exit %v", exit)
			return
		}
		e.ForEach("a", func(_ int, el *colly.HTMLElement) {
			// log.Printf("ForEach %s", el.Text)
			// log.Printf("Contains %s", el.Text)
			if strings.Contains(el.Text, "轻铁") {
				return
			}

			style := el.Attr("style")
			styles := strings.Split(style, ":")
			if styles[0] != "background-color" {
				return
			}
			color := styles[1]
			link := el.Attr("href")

			key := ""
			if strings.Contains(el.Text, "-") {
				key = strings.Split(el.Text, "(")[0]
			} else {
				key = el.Text
			}
			lineKey := ToPy(key)

			index++
			var lineData LineData
			lineData.LineId = strconv.Itoa(index)
			lineData.Key = lineKey
			lineData.LineName = el.Text
			lineData.Color = color[:len(color)-1]
			if _, ok := city.lineMap[lineData.Key]; ok {
				lineData.Key = lineKey + "A"
			}

			log.Printf("text:%s, key:%s, style:%s, link:%s", el.Text, lineData.Key, lineData.Color, link)
			city.Stages(link, &lineData)
			// log.Printf("lineData:%v", lineData)
			city.lineMap[lineData.Key] = &lineData
			city.metro.LineData = append(city.metro.LineData, lineData)
		})
	})

	c.Visit(city.link)
}

func (city *City) Stages(path string, lineData *LineData) {
	c := colly.NewCollector()

	index := 0
	c.OnHTML("table tbody tr", func(e *colly.HTMLElement) {
		// log.Println("table", e.Text)

		var stages Stages
		texts := strings.Split(e.Text, " ")
		link := e.ChildAttr("a", "href")
		// log.Println("texts", texts, len(texts))
		if strings.Contains(texts[1], "/") {
			stages.Name = strings.Split(texts[1], "/")[0]
		} else {
			stages.Name = texts[1]
		}
		index++
		stages.Index = index
		stages.Code = fmt.Sprintf("%s-%s-%d", city.metro.CityKeyPy, lineData.Key, stages.Index)
		stages.EName = ToAllPy(stages.Name)
		stages.RunTime.StartOne = texts[2]
		stages.RunTime.EndOne = texts[4]
		if len(texts) < 6 {
			// log.Fatalln("texts", texts, len(texts))
			stages.RunTime.StartTow = "--"
			stages.RunTime.EndTow = "--"
		} else {
			stages.RunTime.StartTow = texts[3]
			stages.RunTime.EndTow = texts[5]
		}

		if lineData.LineName == "广佛线" {
			stages.Position.Lat, stages.Position.Lng = TencentMapSite(stages.Name, city.metro.City)
			if stages.Position.Lat == 0 {
				time.Sleep(time.Millisecond * 500)
				stages.Position.Lat, stages.Position.Lng = TencentMapSite(stages.Name, "佛山")
			}
			stages.Position.Bdlat, stages.Position.Bdlng = BaiduMapSite(stages.Name, "佛山")
			if stages.Position.Bdlat == 0 {
				time.Sleep(time.Millisecond * 500)
				stages.Position.Bdlat, stages.Position.Bdlat = BaiduMapSite(stages.Name, city.metro.City)
			} else {
				time.Sleep(time.Millisecond * 200)
			}
		} else {
			stages.Position.Lat, stages.Position.Lng = TencentMapSite(stages.Name, city.metro.City)
			if stages.Position.Lat == 0 {
				time.Sleep(time.Millisecond * 500)
				stages.Position.Lat, stages.Position.Lng = TencentMapSite(stages.Name, city.metro.City)
			}
			stages.Position.Bdlat, stages.Position.Bdlng = BaiduMapSite(stages.Name, city.metro.City)
			if stages.Position.Bdlat == 0 {
				time.Sleep(time.Millisecond * 500)
				stages.Position.Bdlat, stages.Position.Bdlat = BaiduMapSite(stages.Name, city.metro.City)
			} else {
				time.Sleep(time.Millisecond * 200)
			}
		}
		city.Doors(link, &stages)
		lineData.Stages = append(lineData.Stages, stages)
	})
	c.Visit(city.link + path)
}

func (city *City) Doors(path string, stages *Stages) {
	c := colly.NewCollector()
	c.OnHTML("table tbody tr td", func(e *colly.HTMLElement) {
		em := e.ChildText("em")
		// log.Println("em", em)
		p := e.ChildText("p")
		// log.Println("p")
		var entrysRes EntrysRes
		entrysRes.EntryName = em
		entrysRes.Res = strings.Split(p, " ")
		stages.EntrysRes = append(stages.EntrysRes, entrysRes)
	})
	c.Visit(city.link + path)
}

// func DealData(dataCh chan *LineData) {
// 	log.Println("Deal data start.")
// 	line := make(map[string]LineData)
// 	for {
// 		select {
// 		case data := <-dataCh:
// 			if data.Key == "finish" {
// 				// obj, _ := json.Marshal(metro)
// 				// CreateFile("./hongkong.json", obj)
// 				log.Println("Finish data start.", line)
// 				os.Exit(0)
// 				return
// 			}
// 			if _, ok := line[data.Key]; ok {
// 				line[data.Key+"A"] = *data
// 			} else {
// 				line[data.Key] = *data
// 			}
// 		}
// 	}
// }

// func ToMetro() {
// 	metro := Metro{Versions: "v0.0.1", City: "香港", CityKey: "hongkong", Map: "http://www.mtr.com.hk/ch/customer/st/index.php"}

// 	lineCnt := make(map[string]*LineData)
// 	a := py.Args{py.FIRST_LETTER, py.Heteronym, py.Separator}
// 	var lineIndex int
// 	for _, value := range ret.Faresaver.Facilities {
// 		lineInfo := strings.Split(value.LINE, "&")
// 		lineNames := py.LazyPinyin(lineInfo[0], a)
// 		// log.Println(lineNames, lineNamesss)
// 		key := fmt.Sprintf("%s%sL", strings.ToUpper(lineNames[0]), strings.ToUpper(lineNames[1]))
// 		if v, ok := lineCnt[key]; ok {
// 			var stages Stages
// 			stages.Index = len(v.Stages) + 1
// 			stages.Code = fmt.Sprintf("HK-%s-%d", v.LineId, stages.Index)
// 			stages.Name = value.STATION_NAME_TC
// 			stages.EName = value.STATION_NAME_EN
// 			v.Stages = append(v.Stages, stages)
// 			lineCnt[key] = v
// 			lineId, _ := strconv.Atoi(v.LineId)
// 			metro.LineData[lineId-1].Stages = v.Stages
// 		} else {
// 			log.Println(key)
// 			var lineData LineData
// 			var stages Stages
// 			lineIndex++
// 			lineData.LineId = strconv.Itoa(lineIndex)
// 			lineData.Key = key
// 			lineData.LineName = lineInfo[0]
// 			// lineData.Color = lineInfo[1][1 : len(lineInfo[1])-1]
// 			stages.Index = 1
// 			stages.Code = fmt.Sprintf("HK-%s-%d", lineData.LineId, stages.Index)
// 			stages.Name = value.STATION_NAME_TC
// 			stages.EName = value.STATION_NAME_EN
// 			lineData.Stages = append(lineData.Stages, stages)
// 			lineCnt[key] = &lineData
// 			metro.LineData = append(metro.LineData, lineData)
// 		}

// 	}

// 	obj, _ := json.Marshal(metro)
// 	CreateFile("./hongkong.json", obj)
// }
